package com.lizicloud.infrastructure.common.utils;

/**
 * XML工具类
 */
public class XmlUtils {
    
    /**
     * 对象转XML字符串
     */
    public static String toXml(Object obj) {
        if (obj == null) {
            return "";
        }
        
        try {
            StringBuilder xml = new StringBuilder();
            xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            
            String className = obj.getClass().getSimpleName();
            xml.append("<").append(className).append(">\n");
            
            // 简单的对象转XML实现
            java.lang.reflect.Field[] fields = obj.getClass().getDeclaredFields();
            for (java.lang.reflect.Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(obj);
                
                if (value != null) {
                    xml.append("  <").append(field.getName()).append(">");
                    xml.append(escapeXml(value.toString()));
                    xml.append("</").append(field.getName()).append(">\n");
                }
            }
            
            xml.append("</").append(className).append(">");
            return xml.toString();
        } catch (Exception e) {
            throw new RuntimeException("对象转XML失败", e);
        }
    }
    
    /**
     * XML字符串转对象
     */
    public static <T> T fromXml(String xml, Class<T> clazz) {
        if (xml == null || xml.isEmpty() || clazz == null) {
            return null;
        }
        
        try {
            T obj = clazz.newInstance();
            
            // 简单的XML解析实现
            String className = clazz.getSimpleName();
            String startTag = "<" + className + ">";
            String endTag = "</" + className + ">";
            
            int start = xml.indexOf(startTag);
            int end = xml.indexOf(endTag);
            
            if (start != -1 && end != -1) {
                String content = xml.substring(start + startTag.length(), end);
                
                java.lang.reflect.Field[] fields = clazz.getDeclaredFields();
                for (java.lang.reflect.Field field : fields) {
                    field.setAccessible(true);
                    
                    String fieldStart = "<" + field.getName() + ">";
                    String fieldEnd = "</" + field.getName() + ">";
                    
                    int fieldStartIndex = content.indexOf(fieldStart);
                    int fieldEndIndex = content.indexOf(fieldEnd);
                    
                    if (fieldStartIndex != -1 && fieldEndIndex != -1) {
                        String fieldValue = content.substring(fieldStartIndex + fieldStart.length(), fieldEndIndex);
                        fieldValue = unescapeXml(fieldValue.trim());
                        
                        // 设置字段值
                        setFieldValue(obj, field, fieldValue);
                    }
                }
            }
            
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("XML转对象失败", e);
        }
    }
    
    /**
     * 格式化XML字符串
     */
    public static String formatXml(String xml) {
        if (xml == null || xml.isEmpty()) {
            return xml;
        }
        
        StringBuilder formatted = new StringBuilder();
        int indentLevel = 0;
        boolean inTag = false;
        boolean inComment = false;
        
        for (int i = 0; i < xml.length(); i++) {
            char c = xml.charAt(i);
            
            if (c == '<') {
                if (xml.substring(i).startsWith("<!--")) {
                    inComment = true;
                } else {
                    inTag = true;
                    if (xml.charAt(i + 1) == '/') {
                        indentLevel--;
                        formatted.append("\n").append(getIndent(indentLevel));
                    } else if (i > 0 && xml.charAt(xml.length() - 1) != '>') {
                        formatted.append("\n").append(getIndent(indentLevel));
                    }
                    indentLevel++;
                }
            } else if (c == '>') {
                if (inComment && xml.substring(i - 2).startsWith("-->")) {
                    inComment = false;
                } else if (inTag) {
                    inTag = false;
                    if (xml.charAt(i - 1) == '/') {
                        indentLevel--;
                    }
                }
            }
            
            formatted.append(c);
        }
        
        return formatted.toString();
    }
    
    /**
     * 检查是否为有效的XML字符串
     */
    public static boolean isValidXml(String xml) {
        if (xml == null || xml.isEmpty()) {
            return false;
        }
        
        try {
            // 简单的XML验证
            xml = xml.trim();
            return xml.startsWith("<?xml") && 
                   xml.contains("<") && 
                   xml.contains(">") && 
                   xml.contains("</");
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 获取XML节点值
     */
    public static String getXmlValue(String xml, String nodeName) {
        if (xml == null || xml.isEmpty() || nodeName == null || nodeName.isEmpty()) {
            return null;
        }
        
        try {
            String startTag = "<" + nodeName + ">";
            String endTag = "</" + nodeName + ">";
            
            int start = xml.indexOf(startTag);
            int end = xml.indexOf(endTag);
            
            if (start != -1 && end != -1) {
                String value = xml.substring(start + startTag.length(), end);
                return unescapeXml(value.trim());
            }
            
            return null;
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 设置XML节点值
     */
    public static String setXmlValue(String xml, String nodeName, String value) {
        if (xml == null || xml.isEmpty() || nodeName == null || nodeName.isEmpty()) {
            return xml;
        }
        
        try {
            String startTag = "<" + nodeName + ">";
            String endTag = "</" + nodeName + ">";
            
            int start = xml.indexOf(startTag);
            int end = xml.indexOf(endTag);
            
            if (start != -1 && end != -1) {
                String newValue = value != null ? escapeXml(value) : "";
                return xml.substring(0, start + startTag.length()) + 
                       newValue + 
                       xml.substring(end);
            }
            
            return xml;
        } catch (Exception e) {
            return xml;
        }
    }
    
    /**
     * XML字符串转义（私有方法）
     */
    private static String escapeXml(String str) {
        if (str == null) {
            return "";
        }
        
        return str.replace("&", "&amp;")
                 .replace("<", "&lt;")
                 .replace(">", "&gt;")
                 .replace("\"", "&quot;")
                 .replace("'", "&apos;");
    }
    
    /**
     * XML字符串反转义（私有方法）
     */
    private static String unescapeXml(String str) {
        if (str == null) {
            return "";
        }
        
        return str.replace("&amp;", "&")
                 .replace("&lt;", "<")
                 .replace("&gt;", ">")
                 .replace("&quot;", "\"")
                 .replace("&apos;", "'");
    }
    
    /**
     * 设置字段值（私有方法）
     */
    private static void setFieldValue(Object obj, java.lang.reflect.Field field, String value) {
        try {
            Class<?> fieldType = field.getType();
            
            if (fieldType == String.class) {
                field.set(obj, value);
            } else if (fieldType == int.class || fieldType == Integer.class) {
                field.set(obj, Integer.parseInt(value));
            } else if (fieldType == long.class || fieldType == Long.class) {
                field.set(obj, Long.parseLong(value));
            } else if (fieldType == double.class || fieldType == Double.class) {
                field.set(obj, Double.parseDouble(value));
            } else if (fieldType == float.class || fieldType == Float.class) {
                field.set(obj, Float.parseFloat(value));
            } else if (fieldType == boolean.class || fieldType == Boolean.class) {
                field.set(obj, Boolean.parseBoolean(value));
            } else if (fieldType == byte.class || fieldType == Byte.class) {
                field.set(obj, Byte.parseByte(value));
            } else if (fieldType == short.class || fieldType == Short.class) {
                field.set(obj, Short.parseShort(value));
            }
        } catch (Exception e) {
            // 忽略设置失败的情况
        }
    }
    
    /**
     * 获取缩进（私有方法）
     */
    private static String getIndent(int level) {
        StringBuilder indent = new StringBuilder();
        for (int i = 0; i < level; i++) {
            indent.append("  ");
        }
        return indent.toString();
    }
    
    private XmlUtils() {
        // 私有构造函数，防止实例化
    }
}